/*
 * Copyright (c) 2000, 2003, Oracle and/or its affiliates. All rights reserved.
 * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 */

package com.sun.corba.se.impl.ior;

import java.util.Collection;
import java.util.List;
import java.util.AbstractList;
import java.util.ListIterator;
import java.util.Iterator;

import com.sun.corba.se.spi.ior.MakeImmutable;

/** Simple class that delegates all List operations to
* another list.  It also can be frozen, which means that
* a number of operations can be performed on the list,
* and then the list can be made immutable, so that no
* further changes are possible.  A FreezableList is frozen
* using the makeImmutable method.
*/
public class FreezableList extends AbstractList {
    private List delegate = null;
    private boolean immutable = false;

    public boolean equals(Object obj) {
        if (obj == null)
            return false;

        if (!(obj instanceof FreezableList))
            return false;

        FreezableList other = (FreezableList) obj;

        return delegate.equals(other.delegate) && (immutable == other.immutable);
    }

    public int hashCode() {
        return delegate.hashCode();
    }

    public FreezableList(List delegate, boolean immutable) {
        this.delegate = delegate;
        this.immutable = immutable;
    }

    public FreezableList(List delegate) {
        this(delegate, false);
    }

    public void makeImmutable() {
        immutable = true;
    }

    public boolean isImmutable() {
        return immutable;
    }

    public void makeElementsImmutable() {
        Iterator iter = iterator();
        while (iter.hasNext()) {
            Object obj = iter.next();
            if (obj instanceof MakeImmutable) {
                MakeImmutable element = (MakeImmutable) obj;
                element.makeImmutable();
            }
        }
    }

    // Methods overridden from AbstractList

    public int size() {
        return delegate.size();
    }

    public Object get(int index) {
        return delegate.get(index);
    }

    public Object set(int index, Object element) {
        if (immutable)
            throw new UnsupportedOperationException();

        return delegate.set(index, element);
    }

    public void add(int index, Object element) {
        if (immutable)
            throw new UnsupportedOperationException();

        delegate.add(index, element);
    }

    public Object remove(int index) {
        if (immutable)
            throw new UnsupportedOperationException();

        return delegate.remove(index);
    }

    // We also override subList so that the result is a FreezableList.
    public List subList(int fromIndex, int toIndex) {
        List list = delegate.subList(fromIndex, toIndex);
        List result = new FreezableList(list, immutable);
        return result;
    }
}
